home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ecstr2.arc / STRREPL.C < prev    next >
C/C++ Source or Header  |  1987-03-04  |  2KB  |  64 lines

  1. /*  File   : strrepl.c
  2.     Author : Richard A. O'Keefe.
  3.     Updated: 23 April 1984
  4.     Defines: strrepl()
  5.  
  6.     strrepl(dst, src, pat, rep, times) copies src to dst, replacing  the
  7.     first "times" non-overlapping instances of pat by rep.  pat is not a
  8.     regex(3) pattern, it is a  literal  string  which  must  be  matched
  9.     exactly.   As  a  special hack, since strfind claims to find "" just
  10.     once at the end of the src string, strrepl does a strcat when pat is
  11.     an empty string "".  If times <= 0, it is just strmov.
  12.  
  13.     The result is a pointer to the NUL which now terminates dst.
  14.  
  15.     BEWARE: even when rep is shorter than pat it is NOT necessarily safe
  16.     for dst to be the same as src.  ALWAYS make sure dst and src do not/
  17.     will not overlap.  You have been warned.
  18.  
  19.     There really ought to be a strnrepl with a bound for the size of the
  20.     destination string, but there isn't.
  21. */
  22.  
  23. #include "strings.h"
  24. #include "_str2pat.h"
  25.  
  26. char *strrepl(dst, src, pat, rep, times)
  27.     char *dst, *src, *pat, *rep;
  28.     int times;
  29.     {
  30.        register char *s, *p;
  31.        register int c, lastch;
  32.  
  33.        pat = _str2pat(pat);
  34.        if (times <= 0) {
  35.          for (p = dst, s = src; *p++ = *s++; ) ;
  36.            return p-1;
  37.        }
  38.        if (_pat_lim < 0) {
  39.            for (p = dst, s = src; *p++ = *s++; ) ;
  40.            for (--p, s = rep; *p++ = *s++; ) ;
  41.            return p-1;
  42.        }
  43.        /*  The pattern is non-empty and times is positive  */
  44.        c = _pat_lim, lastch = pat[c];
  45.        for (;;) {
  46.            for (s = src, p = dst; --c >= 0; )
  47.                if (!(*p++ = *s++)) return p-1;
  48.            c = *s, src = s, dst = p;
  49.            if (c == lastch) {
  50.                for (s -= _pat_lim, p = pat; *p; )
  51.                    if (*s++ != *p++) goto not_yet;
  52.                for (p = dst-_pat_lim, s = rep; *p++ = *s++; ) ;
  53.                --p;
  54.                if (--times == 0) {
  55.                    for (s = src; *p++ = *++s; ) ;
  56.                    return p-1;
  57.                }
  58.              dst = p, src++, c = _pat_lim;
  59.            } else {
  60. not_yet:       c = _pat_vec[c];
  61.            }
  62.        }
  63.     }
  64.